package cn.nfwx.tv.controller.player;

import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v4.app.FragmentManager;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.trello.rxlifecycle2.components.support.RxAppCompatActivity;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import cn.nfwx.tv.R;
import cn.nfwx.tv.callback.ResponseWithFailListener;
import cn.nfwx.tv.helper.DialogFragmentHelper;
import cn.nfwx.tv.manager.TimelineManager;
import cn.nfwx.tv.model.Result;
import cn.nfwx.tv.okhttp.CustomOkHttpClient;
import cn.nfwx.tv.util.AppUtil;
import cn.nfwx.tv.util.GlideUtil;
import cn.nfwx.tv.util.TimeUtil;
import cn.nfwx.tv.widget.nfwxplayer.INfwxVideoPlayer;
import cn.nfwx.tv.widget.nfwxplayer.NfwxVideoPlayerManager;
import cn.nfwx.tv.widget.seekbar.ClipRangeSeekBar;
import cn.nfwx.tv.widget.seekbar.RangeSeekBar;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.CompositeDisposable;
import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;

public class TimelineController extends LinearLayout implements Handler.Callback, RangeSeekBar.OnRangeChangedListener, ResponseWithFailListener<String> {

    private String requestLiveClipsnapCommand;
    private ImageView iv_player_thumb, player_start_btn;
    private View ll_clip;
    private TextView clip_bottom_cancle, clip_bottom_sure, clip_tv_time_start, clip_tv_time_end, time_code;
    private SimpleDateFormat _sf;
    private ClipRangeSeekBar crsb_time;

    private String mLaststartTimeUrl;
    private String mLastEndTimeUrl;

    private final List<String> timeCodes = new ArrayList<>();

    private FragmentManager fragmentManager;

    private INfwxVideoPlayer mijkVideoView;

    private boolean _hasShit;
    private boolean _hasSeek;
    private boolean _hasPlay;

    private boolean _startseek;
    private boolean _endseek;
    private boolean _seeking;
    private Disposable mDisposable;

    public TimelineController(Context context) {
        this(context, null);
    }

    public TimelineController(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TimelineController(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        init();
    }

    private Handler mHandler;

    private void init() {
        if (_sf == null) {
            _sf = new SimpleDateFormat("HH:mm:ss");
        }

        LayoutInflater.from(getContext()).inflate(R.layout.layout_time_view_controller, this, true);
        crsb_time = findViewById(R.id.crsb_time);

        ll_clip = findViewById(R.id.ll_clip);
        clip_bottom_cancle = findViewById(R.id.clip_bottom_cancle);
        clip_bottom_sure = findViewById(R.id.clip_bottom_sure);
        clip_tv_time_start = findViewById(R.id.clip_tv_time_start);
        time_code = findViewById(R.id.time_code);
        clip_tv_time_end = findViewById(R.id.clip_tv_time_end);
        crsb_time.setOnRangeChangedListener(this);
        crsb_time.clearRangseekbar();
    }

    public void setProgramItemListener(OnClickListener clickListener) {
        clip_bottom_cancle.setOnClickListener(clickListener);
        clip_bottom_sure.setOnClickListener(clickListener);
        ll_clip.setOnClickListener(clickListener);
    }

    /**
     * 设置缩略图的
     *
     * @param imageView
     */
    public void setBmpView(ImageView imageView) {
        iv_player_thumb = imageView;
    }

    /**
     * @param playerView
     */
    public void setPlayerView(ImageView playerView) {
        player_start_btn = playerView;
    }

    @Override
    public void onRangeChanged(RangeSeekBar view, float min, float max) {
        pause();
        int start = (int) Math.floor(min);
        int end = (int) Math.ceil(max);
        if (timeCodes.isEmpty()) {
            return;
        }
        String startTimeUrl = timeCodes.get(start);
        String endTimeUrl = timeCodes.get(end);

        String startTimeStr = getTime(startTimeUrl);
        String endTimeStr = getTime(endTimeUrl);
        //clip_tv_time_start.setText(_sf.format(new Date(startTime * 1000L)));
        //clip_tv_time_end.setText(_sf.format(new Date(endTime * 1000L)));

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
        if (!TextUtils.isEmpty(startTimeStr) && !TextUtils.isEmpty(endTimeStr)) {
            try {
                Date date = dateFormat.parse(startTimeStr);
                Date endDate = dateFormat.parse(endTimeStr);

                clip_tv_time_start.setText(_sf.format(date));
                clip_tv_time_end.setText(_sf.format(endDate));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }


        // 设置缩略图
        if (!TextUtils.isEmpty(startTimeUrl) && !startTimeUrl.equals(mLaststartTimeUrl)) {
            iv_player_thumb.setVisibility(VISIBLE);
            _startseek = true;
            GlideUtil.loadImageNotPlace(getContext(), startTimeUrl, iv_player_thumb);
        }

        //
        if (!TextUtils.isEmpty(endTimeUrl) && !endTimeUrl.equals(mLastEndTimeUrl)) {
            iv_player_thumb.setVisibility(VISIBLE);
            _endseek = true;
            GlideUtil.loadImageNotPlace(getContext(), endTimeUrl, iv_player_thumb);
        }
    }

    @Override
    public void onRangeChangedFinish(RangeSeekBar view, float min, float max) {
        if (timeCodes.isEmpty()) {
            return;
        }

        int start = (int) Math.floor(min);
        int end = (int) Math.ceil(max);
        if (end >= timeCodes.size()) {
            return;
        }

        _hasShit = true;

        String laststartTimeUrl = timeCodes.get(start);

        String lastEndTimeUrl = timeCodes.get(end);

        if (!TextUtils.isEmpty(laststartTimeUrl) && _startseek) {
            _hasSeek = true;
            _startseek = false;
            mLaststartTimeUrl = laststartTimeUrl;
            String startTimeStr = getTime(laststartTimeUrl);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
            if (!TextUtils.isEmpty(startTimeStr)) {
                try {
                    Date date = dateFormat.parse(startTimeStr);
                    _seeking = true;
                    mijkVideoView.seekByTimeCode(date.getTime() / 1000L);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        } else if (!TextUtils.isEmpty(lastEndTimeUrl) && _endseek) {
            _hasSeek = false;
            _endseek = false;
            mLastEndTimeUrl = lastEndTimeUrl;
            String endTimeStr = getTime(mLastEndTimeUrl);
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
            if (!TextUtils.isEmpty(endTimeStr)) {
                try {
                    Date date = dateFormat.parse(endTimeStr);
                    _seeking = true;
                    mijkVideoView.seekByTimeCode(date.getTime() / 1000L);
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void onProgressChanged(RangeSeekBar view, float progress) {
        NfwxVideoPlayerManager.instance().suspendVideoPlayer();
        stopControll();
        int start = (int) Math.floor(progress);
        String startTimeUrl = timeCodes.get(start);
        String startTime = getTime(startTimeUrl);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
        if (!TextUtils.isEmpty(startTime)) {
            try {
                Date date = dateFormat.parse(startTime);
                time_code.setText(_sf.format(date));
                iv_player_thumb.setVisibility(VISIBLE);
                GlideUtil.loadImageNotPlace(getContext(), startTimeUrl, iv_player_thumb);
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void onProgressFinish(RangeSeekBar view, float progress) {
        player_start_btn.setVisibility(View.GONE);
        iv_player_thumb.setVisibility(GONE);
        int start = (int) Math.floor(progress);
        String startTimeUrl = timeCodes.get(start);
        String startTime = getTime(startTimeUrl);
        // 时间移动完成
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
        if (!TextUtils.isEmpty(startTime)) {
            try {
                Date date = dateFormat.parse(startTime);
                _hasPlay = true;
                _seeking = true;
                mijkVideoView.seekByTimeCode(date.getTime() / 1000L);
                startControll();
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 时间移动后
     */
    public void seekComplete() {
        if (_seeking) {
            _seeking = false;
        }
        if (!_hasPlay) {
            pause();
            if (crsb_time != null) {
                crsb_time.setShowProgress(false);
            }
            if (iv_player_thumb != null) {
                iv_player_thumb.setVisibility(GONE);
            }
        }
    }

    /**
     * @param fragmentManager
     * @param gid
     */
    public void requestLiveClipsnap(FragmentManager fragmentManager, String gid) {
        this.fragmentManager = fragmentManager;
        DialogFragmentHelper.showLoadingDialog(fragmentManager, "加载中");
        crsb_time.setEnabled(false);
        crsb_time.clearRangseekbar();
        player_start_btn.setVisibility(VISIBLE);
        requestLiveClipsnapCommand = TimelineManager.requestLiveClipsnap(getContext(), gid, this);
    }

    public String getTime(String path) {
        if (!TextUtils.isEmpty(path)) {
            int index = path.lastIndexOf("live-");
            int endindex = path.lastIndexOf(".jpg");
            if (index != -1 && endindex != -1) {
                return path.substring(index + "live-".length(), endindex);
            }
        }
        return "";
    }

    public void play() {
        if (player_start_btn != null) {
            player_start_btn.setVisibility(GONE);
        }
        if (iv_player_thumb != null) {
            iv_player_thumb.setVisibility(GONE);
        }

        if (_hasShit) {
            _hasShit = false;
            if (!_hasSeek) {
                _hasPlay = true;
                crsb_time.setProgress(0);
                crsb_time.setShowProgress(true);
                if (!TextUtils.isEmpty(mLaststartTimeUrl)) {
                    String startTime = getTime(mLaststartTimeUrl);
                    SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
                    try {
                        Date date = dateFormat.parse(startTime);
                        startControll();
                        _seeking = true;
                        mijkVideoView.seekByTimeCode(date.getTime() / 1000L);
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                }
            } else {
                _hasSeek = false;
                crsb_time.setProgress(0);
                crsb_time.setShowProgress(true);
                startControll();
                _seeking = false;
                NfwxVideoPlayerManager.instance().resumeVideoPlayer();
            }
        } else {
            crsb_time.setProgress(0);
            crsb_time.setShowProgress(true);
            startControll();
            _seeking = false;
            _hasPlay = true;
            NfwxVideoPlayerManager.instance().resumeVideoPlayer();
        }
    }

    /**
     * 暂停
     */
    public void pause() {
        _hasPlay = false;
        player_start_btn.setVisibility(View.VISIBLE);
        crsb_time.setShowProgress(false);
        stopControll();
        NfwxVideoPlayerManager.instance().suspendVideoPlayer();
    }

    /**
     * 确定
     */
    public void sure() {
        GlideUtil.loadImage(getContext(), mLaststartTimeUrl, iv_player_thumb);
        iv_player_thumb.setVisibility(GONE);
        pause();
    }

    public void cancel() {
        pause();
        if (iv_player_thumb != null) {
            iv_player_thumb.setVisibility(GONE);
        }
        if (player_start_btn != null) {
            player_start_btn.setVisibility(GONE);
        }
        CustomOkHttpClient.cancleAll(requestLiveClipsnapCommand);
    }

    /**
     * 开始时钟
     */
    public void startControll() {
        mHandler.removeCallbacksAndMessages(null);
        mHandler.post(runnable);
    }

    /**
     * 停止时钟
     */
    public void stopControll() {
        mHandler.removeMessages(0);
    }

    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            mHandler.sendEmptyMessage(0);
            mHandler.postDelayed(runnable, 500);
        }
    };

    @Override
    public boolean handleMessage(Message msg) {
        if (msg.what == 0) {
            double t = mijkVideoView.getTimeCode();
            if (t > 0) {
                time_code.setText(TimeUtil.getFormatHHmmssDate(mijkVideoView.getTimeCode()));
            } else {
                time_code.setText("00:00:00");
            }

            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
            if (!TextUtils.isEmpty(mLastEndTimeUrl)) {
                String endTime = getTime(mLastEndTimeUrl);
                try {
                    Date date = dateFormat.parse(endTime);
                    if (t >= date.getTime() / 1000L) {
                        if (!_seeking) {
                            _hasShit = true;
                            pause();
                        }
                    } else {
                        for (int i = 0; i < timeCodes.size(); i++) {
                            String perTimeUrl = timeCodes.get(i);
                            String perTime = getTime(perTimeUrl);
                            Date preDate = dateFormat.parse(perTime);
                            if ((i + 1) < timeCodes.size()) {
                                String nextTimeUrl = timeCodes.get(i + 1);
                                String nextTime = getTime(nextTimeUrl);
                                Date nextDate = dateFormat.parse(nextTime);
                                if (t > preDate.getTime() / 1000L && t < nextDate.getTime() / 1000L) {
                                    crsb_time.setProgress(i + 1);
                                    break;
                                }
                            }
                        }
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    /**
     * 绑定播放器
     *
     * @param ijkVideoView
     */
    public void attach(INfwxVideoPlayer ijkVideoView) {
        mijkVideoView = ijkVideoView;
        if (mHandler == null) {
            mHandler = new Handler(this);
        }
    }

    /**
     * 清空
     */
    public void release() {
        crsb_time.release();
        mHandler.removeCallbacksAndMessages(null);
        if (mDisposable != null) {
            if (!mDisposable.isDisposed()) {
                mDisposable.dispose();
            }
        }
    }

    public String getStartTimeUrl() {
        return mLaststartTimeUrl;
    }

    public String getEndTimeUrl() {
        return mLastEndTimeUrl;
    }

    @Override
    public void onResponse(String requestTag, final String response) {
        if (requestTag.equals(requestLiveClipsnapCommand)) {
            if (mDisposable != null) {
                if (!mDisposable.isDisposed()) {
                    mDisposable.dispose();
                }
                mDisposable = null;
            }
            RxAppCompatActivity appCompatActivity = (RxAppCompatActivity) AppUtil.getAppCompActivity(getContext());
            Observable.create(new ObservableOnSubscribe<List<String>>() {
                @Override
                public void subscribe(ObservableEmitter<List<String>> emitter) throws Exception {
                    Result<List<String>> result = JSON.parseObject(response, new TypeReference<Result<List<String>>>() {
                    }.getType());
                    emitter.onNext(result.getData());
                    emitter.onComplete();
                }
            }).subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .compose(appCompatActivity.<List<String>>bindToLifecycle())
                    .subscribe(new Observer<List<String>>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            mDisposable = d;
                        }

                        @Override
                        public void onNext(List<String> strings) {
                            timeCodes.clear();
                            timeCodes.addAll(strings);
                            if (!strings.isEmpty()) {
                                //mLastStart = 0;
                                //mLastEnd = timeCodes.size() - 1;
                                String min = timeCodes.get(0);
                                String max = timeCodes.get(timeCodes.size() - 1);
                                mLaststartTimeUrl = min;
                                mLastEndTimeUrl = max;

                                _hasShit = true;
                                _hasSeek = false;

                                String startTimeStr = getTime(mLaststartTimeUrl);
                                String endTimeStr = getTime(mLastEndTimeUrl);

                                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
                                if (!TextUtils.isEmpty(startTimeStr) && !TextUtils.isEmpty(endTimeStr)) {
                                    try {
                                        Date date = dateFormat.parse(startTimeStr);
                                        Date endDate = dateFormat.parse(endTimeStr);

                                        _seeking = true;
                                        mijkVideoView.seekByTimeCode(date.getTime() / 1000L);

                                        clip_tv_time_start.setText(_sf.format(date));
                                        clip_tv_time_end.setText(_sf.format(endDate));
                                    } catch (ParseException e) {
                                        e.printStackTrace();
                                    }
                                }

                                crsb_time.setData(timeCodes);
                                crsb_time.setEnabled(true);
                            }
                        }

                        @Override
                        public void onError(Throwable e) {

                        }

                        @Override
                        public void onComplete() {
                            if (!timeCodes.isEmpty()) {
                                iv_player_thumb.setVisibility(VISIBLE);
                                GlideUtil.loadImageNotPlace(getContext(), timeCodes.get(0), iv_player_thumb);
                            }
                            DialogFragmentHelper.closeLoadingDialog(fragmentManager);
                        }
                    });

        }
    }

    @Override
    public void onError(String requestTag, Throwable t) {

    }

    @Override
    public void onFinish() {

    }

    @Override
    public void onFail(String requestTag, String response) {

    }
}
